package control;


import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

import property.Order;
import property.Sequence;

import User.Uservalidation;
import control.Dictionary;
import control.RequestParameter;
import control.SpecialCharacter;

import utility.CapitalChar;
import utility.Replacesspace;
import dbmanager.DBManager;
import smsBean.SmsBean;
import smsBean.SplitRequest;;

public class SmsControl
{
	
	String Username;
	String Message;	
	DBManager database;
	
	String Password;
	String requestType;	
	int i=0;
	private RequestParameter reqParam;
	private Vector<Object> splitVector=new Vector<Object>();
	Hashtable<Object,Object> ResponseOfMessageParsing = new Hashtable<Object,Object>();
	Hashtable<Object,Object> ResponseOfRequestProcessing = new Hashtable<Object,Object>();	
	boolean flag=false;
	
	/** 
	 * The message send from ControlClass is in the following format, "Username,Message,database".
	 * Here database object is created & through getConnect() of DBManager, connection is created to database. In DBManager class, object of Logger class is created. Also init() of Column class is invoked,  in which FileUtility class' object is created for getting indices of mid,pid,pv,vt,ref which are the fields of property_details table.
	 * When a message is passed, constructor of ControlClass is invoked where username, ie mobile no., message, ie request or order, & database object are passed as parameters. Here replacesspace() of Replacesspace class is also called to trim spaces in the message.  
	 * @param Username as a parmeter of the control class, and is mobile number provided to every users.  
	 * @param Message as a parmeter of the control class, and is any type of message for any table.  
	 * @param database as a parmeter of the control class.
	 **/
	public SmsControl(String Username, String Message,DBManager database)
	{
		this.database = database;
		this.Username = Username;
		this.Message = Message;
	}
	
	
	/**
	 * In ControlClass class validation of user is done through invoking UserValidation class through messageprocessing. 
	 * @return ResponseOfMessageParsing as a result of parsig 
	 * the input.
	 */
	public Hashtable<Object,Object> messageProcessing()
	{
		try
		{		
			try 
			{
				SpecialCharacter cp1 = new SpecialCharacter();
				int start = cp1.getNextSpChar(0, Message.toCharArray());
				String usernameMessage= Message.substring(start);
				String init = Message.substring(0, start);
				String replacerequest = Replacesspace.replacesspace(usernameMessage);
				if(replacerequest.equals("ERROR"))
					this.Message = replacerequest;
				else
					this.Message  =init + replacerequest;		
				
			} 
			catch (Exception e)
			{
				this.Message  = Replacesspace.replacesspace(Message);
			}
			
			
			Uservalidation validateUser = new Uservalidation(database);
			
			//DataInput;
			String parseMessage = Message;
			System.out.println("control::ControlClass::messageProcessing()::Message Obtained in ControlClass is :--> "+Message);
			
			
			
			reqParam = new RequestParameter();
			Sequence sequence =new Sequence();
			sequence.setDbmanager(database);
			Stack<Object> input =new Stack<Object>();
			input=sequence.getResult(Message, Username);
			reqParam.setKeyword(sequence.keyword);			
			if(sequence.msg.length()>0)
			{
				parseMessage =sequence.msg;
			}	
			Enumeration<Object>enumer=  input.elements();

			while(enumer.hasMoreElements())
			{
				String request=enumer.nextElement().toString();
				if(!splitVector.contains(request))
					splitVector.add(request);
				flag = false;
			}
			if(input.empty())
				flag = true;
			
			if(flag)
			{
				Dictionary dict = new Dictionary(database,Username);
				parseMessage = dict.parse(parseMessage);
			
				if(parseMessage.equalsIgnoreCase("ERROR"))
				{

					ResponseOfMessageParsing.put("Error", "Unable to Parse Input String Please check dictionary");
					System.out.println("control::ControlClass::messageProcessing()::You are not Authorized User");
					ResponseOfMessageParsing.put("Error", "Unable to find user name and password");
					
					return ResponseOfMessageParsing;
				}
				
				
				
				parseMessage = reqParam.splitRequest(parseMessage);
				reqParam.setUsername(Username);
				
				if(parseMessage.contains("ERROR"))
				{
					ResponseOfMessageParsing.put("Error", parseMessage);
					return ResponseOfMessageParsing;
				}
				
				requestType = reqParam.getRequest();
				System.out.println("\ncontrol::ControlClass::messageProcessing():: Request Type :"+requestType);
				
				Password = reqParam.getPassword();
				
				//USER password VALIDATION 
				try
				{
					if(validateUser.validate_User(Username, Password)==false)
					{
						System.out.println("control::ControlClass::messageProcessing()::You are not Authorized User");
						ResponseOfMessageParsing.put("Error", "Please check user name and password");
						return ResponseOfMessageParsing;
					}	
				}
				catch(Exception e)
				{
					System.out.println("control::ControlClass::messageProcessing():: Exception : "+e.getMessage());
				}
				Message = parseMessage;
				
				Order order = new Order(database);
				Message=order.getMasterMessage(reqParam.getRequest(), reqParam.getMessage(), reqParam.getProcess());
				
				reqParam.setMessage(Message);
				
				System.out.println("\n\ncontrol::ControlClass::messageProcessing()::Message to forward is : "+Message);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
			ResponseOfMessageParsing.put("Error", "Unable to Parse Input String");
		}
		return ResponseOfMessageParsing;
	}
	
	
	/**
	 * In requestProcess() C is a object of the class dynamically binds the classes and interfaces. 
	 * @return ResponseOfRequestProcessing as a the Class object associated with the
	 * class or interface according to the request type.	 
	 * It returns hashtable which contains the key ad value pair of the fields, 
	 * which checks whether message contains properties for  that particular 
	 * request or not.
	 **/
	@SuppressWarnings("unchecked")
	public Hashtable<Object,Object> requestProcess()
	{
		try
		{		
			Class C = Class.forName("smsBean.Sms"+CapitalChar.makeFirstCharCapital(requestType));
			SmsBean bean = (SmsBean) C.newInstance();
			
			bean.setDBManager(database);
			bean.setRequestParameter(reqParam);			
			
			//CALL PROCESS
			ResponseOfRequestProcessing.putAll(bean.processSms());			
			
			System.out.println("control::ControlClass::requestProcess()::In RequestProcess");
			bean = null;
			C = null; 
		}
		
		catch (ClassNotFoundException e) 
		{
			e.printStackTrace();
		}
		catch (InstantiationException e) 
		{
			e.printStackTrace();
		}
		catch (Exception e) 
		{
			e.printStackTrace();
			ResponseOfRequestProcessing.put("Error", "Unable to Parse Input String");
		}
		System.out.println("control::ControlClass::requestProcess()::Final Response is :-> "+ResponseOfRequestProcessing);
		return ResponseOfRequestProcessing;
	}	
	
	
	public Vector<Object> splitRequest()
	{	
		
		Vector<Object> splitTemp = new Vector<Object>();
		
		SplitRequest split=new SplitRequest();
		
		splitVector= split.splitRequest(Message);
		
		try
		{
			if(splitVector.isEmpty())
			{
				splitTemp.add(" Please refer the given manual......");
			}
			else
				for(i=0;i<splitVector.size();i++)
				{
					Message=(String)splitVector.get(i);				
					Message=Message.trim();
					Message=split.TrimMessage(Message);
					
					System.out.println("msg = "+Message);
					/*try
					{
						this.Message = Message.substring(0, Message.indexOf('*'))+ Replacesspace.replacesspace(Message.substring(Message.indexOf('*')));
					} catch (Exception e) 
					{
						this.Message = Replacesspace.replacesspace(Message);
					}
					*/
					Hashtable<Object, Object> reply = messageProcessing();
					if(flag)
					if(reply.containsKey("Error")==false )
					{
						requestProcess();
						int j=i+1;
						splitTemp.add(ResponseOfRequestProcessing);
						//splitTemp.add("[" + j + "]"+"  "+requestType+":  "+ResponseOfRequestProcessing);
					}
					else
					{
						System.out.println(reply + " Please refer the given manual......");		
						Hashtable<Object, Object> temp =new Hashtable<Object, Object>();
						temp.putAll(reply);
						//splitTemp.add(reply+ " Please refer the given manual......");
						splitTemp.add(temp);
//						ResponseOfRequestProcessing.clear();
						ResponseOfMessageParsing.clear();
					}
				}
			System.out.println(splitTemp);
		}	
		catch (Exception e)	{
		}
		
		return splitTemp;
	}	
	
	
	public static void main(String[] args)
	{
		 
		DBManager database = new DBManager();
		database.getConnect();
		
		
		
		            /*****************************       ADD          ******************************************/
		
		//SmsControl control = new SmsControl("+919922918605","11 master_table add *aaa61 |type:item #605",database); //
		
		//SmsControl control = new SmsControl("+919922918605","11 property_details add *aaa61|product :aab#605",database);
		
		//SmsControl control = new SmsControl("+919922918602","11 transaction add *po<abb>aaa ,abb115?product :item ,adc21 ?product :item#mag",database);//|reference :aaa |reference:abb?product:item?color:white
		
		//SmsControl control = new SmsControl("+919922918605","11 trans_property_details add *680|reference:abb|reference:ada#605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 transaction_details add *675,ada260?color:pink?color:red,abb434?color:white#605",database);////
		
		//SmsControl control = new SmsControl("+919922918605","11 td_property_details add *674,adb60?product:Lux?product:Rin#605",database);//,abb40?product:Rin
		
		//SmsControl control = new SmsControl("+919922918605","11 dictionary add *\"Have a nice day to OSC \":dghad#605",database); 
		
		//SmsControl control = new SmsControl("+919922918605","11 rate_master add *Lux:10?Buy>piece<\"2007-07-01\",\"2007-07-13 \" |VG1 #605",database);
		
		
		/******************************************         MOD         ********************************************************/
		
		//SmsControl control = new SmsControl("+919922918605","11 master_table mod ,aaa45*aaa4a #605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 property_details mod *aaa45 $type:product |type:item #605",database);//
		
		//SmsControl control =new SmsControl("+919960613969","11 transaction mod @674$acc:ADC#605",database);/*E*///>acd<abc
		
		//SmsControl control = new SmsControl("+919960613969","11 trans_property_details mod *674$Reference:adb|Reference:abb#605",database);/*E*///$Reference:adc|Reference:add
		
		//SmsControl control = new SmsControl("+919922918605","11 transaction_details mod *674$adb200,adb60#605",database);/*E*/// $adb200,adb20
		
		//SmsControl control = new SmsControl("+919922918605","11 td_property_details mod *674,adb200@product:Parle?product:Lux#605",database);//@product:Marie?product:Rin
		
		//SmsControl control = new SmsControl("+919922918605","11 dictionary mod ,\"Have a nice day to Dolly \" *\"Have a nice day to all \"#605",database);
				
		//SmsControl control = new SmsControl("+919922918605","11 dictionary mod $aghad:nghad#605",database);//*\"Have a nice day to all \"
		
		/******************************************         VIEW         ********************************************************/
		
		//SmsControl control = new SmsControl("+919922918605","11 master_table view *aaa46#605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 property_details view |type:Storage#605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 transaction view @670 #605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 trans_property_details view |reference:adb#605",database);/*E/
		
		//SmsControl control = new SmsControl("+919922918605","11 transaction_details view @674,adb200#605",database);/*E*/
		
		//SmsControl control = new SmsControl("+919922918605","11 td_property_details view ?color:white#605",database);/*E*/
		
		//SmsControl control = new SmsControl("+919922918605","11 dictionary view :GsdcF#605",database);
		
		//SmsControl control = new SmsControl("+919922918605","11 dictionary view *\"11 dictionary add\":da#605",database);//:da
		
		//SmsControl control = new SmsControl("+919922918605","11 rate_master view ?mrp #605",database);
			
		/***************************************************************************   MULTIPLE REQUESTS       ****************************************************************************/
		
		//SmsControl control = new SmsControl("+919922918605","11 master_table (add *ABC |name(:shrijita:Kirti:Namita) |city(:pune:Latur:Mumbai)#mod ,lmn*pqr)#11 transaction (add *po(<aab>aac,aaa20# <aac>aad,aaa50 )#mod,abc *pqr)#605",database);
		
		//SmsControl control = new SmsControl("+919922918605","   11      transaction    add  *  PO  <  aaa  >  adc |  Reference (   :   adc  :   aaa  :    abb) , aaa20 #  11   trans_property_details   (    add  *  2 |     Reference (   :  shriji   :kirti  :Namita),  aba20  #   mod    *79|Reference$ffff:adc!  0  )   #605",database); /*E*/
		
		//11 master_table (add *DMA |name(:shrijita:Kirti:Namita) |city(:pune:raipur:Mumbai)#mod ,GMA*DMA)#11 transaction (add *po(<aab>aac,aga20# <aac>aad,agb50 )#mod $abc :pqr)#11 dictionary add *Good Day :goday#891
		
		
		/********************************************************************************    DEL    ******************************************************************/
		
		SmsControl control = new SmsControl("+919922918605","11 property_details Del * fghhhggl | type : 1376544#605",database);
		
		control.splitRequest();	
		
		
		
	}
}
